package gxprod.androidai.support;

import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Parses Dates that are relative to today like "next tuesday" or "tomarrow afternoon" or next week.
 * Don't instance this class, it will just use up resources.
 * @author Josh Maleszewski
 */

public class DateParsing {

	public static final String[] ALL_NAMES 
	= new String[] { "sunday", "monday", "tuesday", "wednesday", "thurdsay",
		"friday", "saturday", "yesterday", "today", "tomarrow", "week", "month" };

	public static final String[] PREFIX_MODIFIERS = { "this", "comming", "next", "last", };
	public static final String[] SUFFIX_MODIFIERS = { "morning", "before noon", "at noon",
		"arround noon", "after noon", "afternoon", "evening" };

	public static DateMatch parseDate(String val) {

		DateMatch match = new DateMatch();
		Date d;
		try {
			d = new Date(Date.parse(val));
			match.date = d;
			match.earliestDate = d;
			match.latestDate = d;
			return match;
		} catch(Exception ex) { }
		
		val = val.replace(", ", " ").replace("  ", " ").toLowerCase();
		String[] parts = val.split("[ \\/\\-\\\\]");
		int coreIndex = -1;
		int partIndex = -1;

		for(int p = 0; p < parts.length; p++) {
			String prt = parts[p];
			for(int i = 0; i < ALL_NAMES.length; i++) {
				if(prt.contains(ALL_NAMES[i])) {
					coreIndex = i;
					partIndex = p;
					p = parts.length;
					continue;
				}
			}
		}

		if(coreIndex == -1)
			return null;

		String before = "", after = ""; 

		if(partIndex != 0)
			for(int i = 0; i < partIndex; i++) 
				before += parts[i];

		if(partIndex != parts.length - 1)
			for(int i = partIndex + 1; i < parts.length; i++) 
				after += parts[i];

		Date exact = new Date(), 	earliest = new Date(),		latest = new Date();

		earliest.setSeconds(0);
		earliest.setMinutes(0);
		earliest.setHours(6);

		latest.setSeconds(59);
		latest.setMinutes(59);
		latest.setHours(23);

		switch(coreIndex) {
			default: // sunday-satrday
				if(exact.getDay() > coreIndex) 		
					exact.setDate(exact.getDate() + coreIndex - exact.getDay());
				else 			exact.setDate(exact.getDate() + coreIndex + 7 - exact.getDay());
				break;				
			case 7:		// yesterday
				exact.setDate(exact.getDate() - 1);
				break;				
			case 8:		// today
				break;				
			case 9:		// tomarrow
				exact.setDate(exact.getDate() - 1);
				break;				
			case 10:	// week
				earliest.setDate(earliest.getDate() - earliest.getDay());
				latest.setDate(earliest.getDate() + 7);
				break;				
			case 11:	// month
				// TODO: implement month range
				break;				
			case 12: 	// year
				earliest.setMonth(0);
				latest.setDate(-1);
				latest.setMonth(11);
				break;
		}

		for(int i = 0; i < PREFIX_MODIFIERS.length; i++) {
			if(before.contains(PREFIX_MODIFIERS[i])) {
				switch(i) {
					case 0:			// this
					default:		// other
						break;

					case 1:			// Comming
						if(!exact.after(new Date()))	// if the set date is not after today, move fowards 1 week
							break;

					case 2:			// next
						exact.setDate(exact.getDate() + 7);
						earliest.setDate(earliest.getDate() + 7);
						latest.setDate(latest.getDate() + 7);
						break;

					case 3:			// last
						exact.setDate(exact.getDate() - 7);
						earliest.setDate(earliest.getDate() - 7);
						latest.setDate(latest.getDate() - 7);
						break;
				}
			}
		}


		String[] SUFFIX_MODIFIERS = { 
				"morning", "before noon", "at noon",
				"arround noon", "after noon", 
				"afternoon", "evening" };


		if(parts[partIndex].equalsIgnoreCase("week") | 
				parts[partIndex].equalsIgnoreCase("month") | 
				parts[partIndex].equalsIgnoreCase("year") ) {


			for(int i = 0; i < SUFFIX_MODIFIERS.length; i++) {
				if(after.contains(SUFFIX_MODIFIERS[i])) {
					switch(i) {
						case 0:			// morning
						case 1:			// before noon
							latest.setHours(11);
							latest.setMinutes(0);
							break;
						case 2:			// at noon
						case 3:			// arround noon
							exact.setDate(exact.getDate() + 7);
							earliest.setDate(earliest.getDate() + 7);
							latest.setDate(latest.getDate() + 7);
							break;

						case 4:			// after noon
						case 5:			// afternoon
							exact.setDate(exact.getDate() - 7);
							earliest.setDate(earliest.getDate() - 7);
							latest.setDate(latest.getDate() - 7);
							break;
					}
				}
			}
		}
		return match;
	}

	private static final Pattern pattern = Pattern.compile("(this|last|this comming|next) (sunday|monday|tuesday|wednesday|thursday|friday|saturday|day|tomarrow)( (morning|a(fter|after |rround |t )noon|after noon|before noon|evening))?");

	public static String getDateContent(String input) {
		try {
			Matcher m = pattern.matcher(input);
			return m.group(0); 
		} catch(Exception ex) {
			ex.printStackTrace();
			return "";
		}
	}

	public static class DateMatch {
		public Date date;
		public Date earliestDate;
		public Date latestDate;
	}
}
